package principal;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.en.EnglishAnalyzer;
import org.apache.lucene.analysis.util.CharArraySet;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;

public class Indexador {	

//	private String diretorioDosIndices = System.getProperty("user.home")
//			+ "/Lucene/Lucene/indice-lucene";
//
//	private String diretorioParaIndexar = System.getProperty("user.home")
//			+ "/Lucene/Lucene/dados";
	
	public static final String SEPARATOR = System.getProperty("file.separator");
		
	private String diretorioDosIndices = System.getProperty("user.dir")
			+ SEPARATOR +"indice-lucene";

	private String diretorioParaIndexar = System.getProperty("user.dir")
			+ SEPARATOR +"dados";

	private IndexWriter writer;
	
	public void indexarBase() {
		Indexador indexador = new Indexador();
		indexador.indexaArquivosDoDiretorio();
	}
	
	public void indexaArquivosDoDiretorio() {
		File diretorio = new File(diretorioDosIndices);
		apagaIndices(diretorio);

		Directory d;
		try {
			d = new SimpleFSDirectory(diretorio);			

			CharArraySet stopWord = new CharArraySet(Version.LUCENE_43, recuperarListaStopwords(), true);
			Analyzer analyzer = new EnglishAnalyzer(Version.LUCENE_43, stopWord);
			IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_43, analyzer);

			writer = new IndexWriter(d, config);
			//long inicio = System.currentTimeMillis();
			indexaArquivosDoDiretorio(new File(diretorioParaIndexar));

			writer.commit();
			writer.close();
			//long fim = System.currentTimeMillis();
			//long tempoFinal = ((fim - inicio) / 1000);
			//String mensagemTempo = "Tempo para indexar: " + tempoFinal + "s";
			//System.out.println(mensagemTempo);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void apagaIndices(File diretorio) {
		if (diretorio.exists()) {
			File arquivos[] = diretorio.listFiles();
			for (File arquivo : arquivos) {
				arquivo.delete();
			}
		}
	}
	
	public void indexaArquivosDoDiretorio(File raiz) {
		for (File arquivo : raiz.listFiles()) {
			if (arquivo.isFile()) {
				//System.out.println("Indexando arquivo " + arquivo.getName());

				try {
					BufferedReader arquivoBufferizado = new BufferedReader(new InputStreamReader(new FileInputStream(arquivo), "UTF-8"));
					String linha;
					Document documento = new Document();
					linha = arquivoBufferizado.readLine();
					
					while(arquivoBufferizado.ready()) {						
						
						if (linha.startsWith("PN ")) {
							documento = new Document();
							//System.out.println("PN do artigo: " + linha.substring(3, 8));
							IntField pn = new IntField("PapelNumber", Integer.parseInt(linha.substring(3, 8)), Store.YES);
							documento.add(pn);
							linha = arquivoBufferizado.readLine();
						}
						
						if (linha.startsWith("RN ")) {
							//System.out.println("Ordem do artigo: " + linha.substring(3, 8));
							IntField rn = new IntField("RecordNumber", Integer.parseInt(linha.substring(3, 8)), Store.YES);
							documento.add(rn);
							linha = arquivoBufferizado.readLine();
						}
						
						if (linha.startsWith("AU ")) {
							String[] autoresSplit = linha.substring(3).split("\\.");
							List<String> autores = new ArrayList<String>();
							autores.addAll(Arrays.asList(autoresSplit));
							linha = arquivoBufferizado.readLine();
							
							while (linha.length() > 1 && linha.substring(0,1).equals(" ")) {
								autoresSplit = linha.split("\\.");
								autores.addAll(Arrays.asList(autoresSplit));
								linha = arquivoBufferizado.readLine();
							}
							
							//System.out.println("Autor: ");
							for (String autor : autores) {
								//System.out.println(autor.trim());
								StringField au = new StringField("Author", autor.trim(), Store.YES);
								documento.add(au);
							}
						}
						
						if (linha.startsWith("TI ")) {
							StringBuilder titulo = new StringBuilder();	
							titulo.append(linha.substring(3).trim());
							
							linha = arquivoBufferizado.readLine();
							
							while (linha.length() > 1 && linha.substring(0,1).equals(" ")) {
								titulo.append(linha.trim());
								linha = arquivoBufferizado.readLine();
							}
							//System.out.println("Titulo: \n" + titulo.toString());
							TextField ti = new TextField("Title", titulo.toString(), Store.YES);
							//ti.setBoost(1.0F);
							documento.add(ti);
						}
						
						if (linha.startsWith("SO ")) {
							StringBuilder fonte = new StringBuilder();	
							fonte.append(linha.substring(3));
							
							linha = arquivoBufferizado.readLine();
							
							while (linha.length() > 1 && linha.substring(0,1).equals(" ")) {
								fonte.append(linha.trim());
								linha = arquivoBufferizado.readLine();
							}
							//System.out.println("Fonte: \n" + fonte.toString());
							StringField so = new StringField("Source", fonte.toString(), Store.YES);
							documento.add(so);
						}
						
						if (linha.startsWith("MJ ")) {
							String[] assuntosSplit = linha.substring(3).split("\\.");
							List<String> assuntosPrincipais = new ArrayList<String>(); 
							assuntosPrincipais.addAll(Arrays.asList(assuntosSplit));
							linha = arquivoBufferizado.readLine();
							
							while (linha.length() > 1 && linha.substring(0,1).equals(" ")) {
								assuntosSplit = linha.split("\\.");
								assuntosPrincipais.addAll(Arrays.asList(assuntosSplit));
								linha = arquivoBufferizado.readLine();
							}
							
							//System.out.println("Assunto Primc.: ");
							for (String assunto : assuntosPrincipais) {
								//System.out.println(assunto.trim());
								TextField mj = new TextField("MajorSubjects", ((assunto.contains(":") ? assunto.substring(0, assunto.indexOf(":")).trim().replace('-', ' ').toLowerCase() : assunto.trim().replace('-', ' ').toLowerCase())), Store.YES);
								//mj.setBoost(3.00F);
								documento.add(mj);
							}
						}
						
						if (linha.startsWith("MN ")) {
							String[] assuntosSplit = linha.substring(3).split("\\.");
							List<String> assuntosSecundarios = new ArrayList<String>();
							assuntosSecundarios.addAll(Arrays.asList(assuntosSplit));
							linha = arquivoBufferizado.readLine();
							
							while (linha.length() > 1 && linha.substring(0,1).equals(" ")) {
								assuntosSplit = linha.split("\\.");
								assuntosSecundarios.addAll(Arrays.asList(assuntosSplit));
								linha = arquivoBufferizado.readLine();
							}
							
							//System.out.println("Assunto Sec.: ");
							for (String assunto : assuntosSecundarios) {
								//System.out.println(assunto.trim());
								TextField mn = new TextField("MinorSubjects", ((assunto.contains(":") ? assunto.substring(0, assunto.indexOf(":")).trim().replace('-', ' ').toLowerCase() : assunto.trim().replace('-', ' ').toLowerCase())), Store.YES);							
								//mn.setBoost(2.00F);
								documento.add(mn);
							}
						}
						
						if (linha.startsWith("EX ") || linha.startsWith("AB ")) {
							StringBuilder resumo = new StringBuilder();	
							resumo.append(linha.substring(3));
							
							linha = arquivoBufferizado.readLine();
							
							while (linha.length() > 1 && linha.substring(0,1).equals(" ")) {
								resumo.append(linha.trim());
								linha = arquivoBufferizado.readLine();
							}
							//System.out.println("Resumo: \n" + resumo.toString());
							TextField ab = new TextField("Abstract", resumo.toString(), Store.YES);
							//ab.setBoost(5.00F);
							documento.add(ab);
						}
						
						if (linha.startsWith("RF ")) {
							List<String> referencias = new ArrayList<String>();
							referencias.add(linha.substring(3));
							
							linha = arquivoBufferizado.readLine();
							
							while (linha.length() > 1 && linha.substring(0,1).equals(" ")) {
								referencias.add(linha);
								linha = arquivoBufferizado.readLine();
							}
							
							//System.out.println("Referencias: ");
							for (String referencia : referencias) {
								//System.out.println(referencia.trim());
								StringField rf = new StringField("References", referencia.trim().replace("\\t", ""), Store.YES);
								documento.add(rf);
							}
						}
						
						if (linha.startsWith("CT ")) {
							List<String> citacoes = new ArrayList<String>();
							citacoes.add(linha.substring(3));
							
							linha = arquivoBufferizado.readLine();
							
							while (linha.length() > 1 && linha.substring(0,1).equals(" ")) {
								citacoes.add(linha);
								linha = arquivoBufferizado.readLine();
							}
							
							//System.out.println("Citacoes: ");
							for (String citacao : citacoes) {
								//System.out.println(citacao.trim());
								StringField ct = new StringField("Citations", citacao.trim().replace("\\t", ""), Store.YES);
								documento.add(ct);
							}
						} else {
							//System.out.println(linha);
							linha = arquivoBufferizado.readLine();
							continue;
						}
						
						//System.out.println("Guardando documento");
						writer.addDocument(documento);
						
					}
					
					arquivoBufferizado.close();
					
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public List<String> recuperarListaStopwords() throws IOException {
		File stopwords = new File(diretorioParaIndexar + SEPARATOR + "stopwords.txt");
		BufferedReader arquivoBufferizado = new BufferedReader(new InputStreamReader(new FileInputStream(stopwords), "UTF-8"));
		String linha;
		linha = arquivoBufferizado.readLine();
		List<String> listaStopwords = new ArrayList<String>();
		
		while(arquivoBufferizado.ready()) {
			listaStopwords.add(linha);
			linha = arquivoBufferizado.readLine();
		}
		arquivoBufferizado.close();
		return listaStopwords;
	}
}